#include "screenviewer.h"

ScreenViewer::ScreenViewer(QWidget *parent)
    : QWidget(parent),
      controlEnabled(true),
      scaleMode(ScaleKeepRatio),
      drawIndicators(true)
{
    // 设置窗口属性
    setAttribute(Qt::WA_OpaquePaintEvent);
    setFocusPolicy(Qt::StrongFocus);  // 允许通过点击和Tab键获取焦点
    setMouseTracking(true);           // 跟踪鼠标移动，即使没有按下鼠标按钮
    
    // 设置最小大小
    setMinimumSize(320, 240);
    
    LOG_INFO("屏幕查看器初始化完成");
}

ScreenViewer::~ScreenViewer()
{
}

void ScreenViewer::setImage(const QByteArray &imageData)
{
    if (loadImage(imageData)) {
        // 图像加载成功，重绘界面
        update();
    }
}

void ScreenViewer::setRemoteScreenSize(int width, int height)
{
    if (width > 0 && height > 0 && (remoteScreenSize.width() != width || remoteScreenSize.height() != height)) {
        remoteScreenSize = QSize(width, height);
        LOG_INFO(QString("远程屏幕尺寸已设置为 %1x%2").arg(width).arg(height));
        emit screenSizeChanged(width, height);
        update();
    }
}

QSize ScreenViewer::getRemoteScreenSize() const
{
    return remoteScreenSize;
}

void ScreenViewer::setControlEnabled(bool enabled)
{
    controlEnabled = enabled;
    setCursor(enabled ? Qt::ArrowCursor : Qt::ForbiddenCursor);
    LOG_INFO(QString("远程控制%1").arg(enabled ? "已启用" : "已禁用"));
}

bool ScreenViewer::isControlEnabled() const
{
    return controlEnabled;
}

void ScreenViewer::setScaleMode(ScaleMode mode)
{
    if (scaleMode != mode) {
        scaleMode = mode;
        update();
        
        QString modeStr;
        switch (mode) {
        case NoScale:
            modeStr = "无缩放";
            break;
        case ScaleToFit:
            modeStr = "适应窗口";
            break;
        case ScaleKeepRatio:
            modeStr = "保持比例";
            break;
        }
        
        LOG_INFO(QString("缩放模式已设置为: %1").arg(modeStr));
    }
}

void ScreenViewer::setDrawIndicators(bool draw)
{
    drawIndicators = draw;
    update();
}

void ScreenViewer::paintEvent(QPaintEvent *event)
{
    Q_UNUSED(event);
    
    QPainter painter(this);
    
    // 使用平滑缩放
    painter.setRenderHint(QPainter::SmoothPixmapTransform, true);
    
    // 填充背景
    painter.fillRect(rect(), Qt::black);
    
    // 如果远程屏幕图像为空，则显示提示信息
    if (remoteScreen.isNull()) {
        painter.setPen(Qt::white);
        painter.drawText(rect(), Qt::AlignCenter, "等待远程屏幕数据...");
        return;
    }
    
    // 计算绘制区域
    QRect targetRect;
    
    switch (scaleMode) {
    case NoScale:
        // 不缩放，原始大小显示
        targetRect = QRect(0, 0, remoteScreen.width(), remoteScreen.height());
        
        // 如果图像大于窗口，则将其居中
        if (remoteScreen.width() > width() || remoteScreen.height() > height()) {
            targetRect.moveCenter(rect().center());
        }
        break;
        
    case ScaleToFit:
        // 缩放以适应窗口大小
        targetRect = rect();
        break;
        
    case ScaleKeepRatio:
        // 保持宽高比
        targetRect = rect();
        
        qreal scaleX = (qreal)width() / remoteScreen.width();
        qreal scaleY = (qreal)height() / remoteScreen.height();
        qreal scale = qMin(scaleX, scaleY);
        
        int newWidth = remoteScreen.width() * scale;
        int newHeight = remoteScreen.height() * scale;
        
        targetRect.setSize(QSize(newWidth, newHeight));
        targetRect.moveCenter(rect().center());
        break;
    }
    
    // 绘制远程屏幕图像
    painter.drawImage(targetRect, remoteScreen);
    
    // 绘制鼠标指示器
    if (drawIndicators && controlEnabled) {
        QPoint cursorPos = lastCursorPos;
        
        // 绘制一个简单的十字光标
        painter.setPen(QPen(Qt::red, 2));
        painter.drawLine(cursorPos.x() - 10, cursorPos.y(), cursorPos.x() + 10, cursorPos.y());
        painter.drawLine(cursorPos.x(), cursorPos.y() - 10, cursorPos.x(), cursorPos.y() + 10);
        
        // 绘制一个圆圈
        painter.setPen(QPen(Qt::red, 1));
        painter.drawEllipse(cursorPos, 5, 5);
    }
    
    // 绘制控制状态指示
    if (!controlEnabled) {
        painter.setPen(QPen(Qt::red, 2));
        painter.drawText(10, 20, "控制已禁用");
    }
}

void ScreenViewer::mousePressEvent(QMouseEvent *event)
{
    if (!controlEnabled || remoteScreen.isNull()) {
        return;
    }
    
    // 获取在远程屏幕上的坐标
    QPoint remotePos = mapToRemote(event->pos());
    
    // 转换Qt鼠标按钮到自定义值
    int button;
    switch (event->button()) {
    case Qt::LeftButton:
        button = 1;
        break;
    case Qt::RightButton:
        button = 2;
        break;
    case Qt::MiddleButton:
        button = 3;
        break;
    default:
        button = 0;
        break;
    }
    
    LOG_INFO(QString("鼠标按下: 位置=(%1,%2), 按钮=%3")
             .arg(remotePos.x()).arg(remotePos.y()).arg(button));
    
    emit mousePressed(remotePos.x(), remotePos.y(), button);
}

void ScreenViewer::mouseReleaseEvent(QMouseEvent *event)
{
    if (!controlEnabled || remoteScreen.isNull()) {
        return;
    }
    
    // 获取在远程屏幕上的坐标
    QPoint remotePos = mapToRemote(event->pos());
    
    // 转换Qt鼠标按钮到自定义值
    int button;
    switch (event->button()) {
    case Qt::LeftButton:
        button = 1;
        break;
    case Qt::RightButton:
        button = 2;
        break;
    case Qt::MiddleButton:
        button = 3;
        break;
    default:
        button = 0;
        break;
    }
    
    LOG_INFO(QString("鼠标释放: 位置=(%1,%2), 按钮=%3")
             .arg(remotePos.x()).arg(remotePos.y()).arg(button));
    
    emit mouseReleased(remotePos.x(), remotePos.y(), button);
}

void ScreenViewer::mouseMoveEvent(QMouseEvent *event)
{
    if (remoteScreen.isNull()) {
        return;
    }
    
    // 保存最后的光标位置，用于绘制指示器
    lastCursorPos = event->pos();
    
    if (!controlEnabled) {
        // 仅更新视图以显示光标位置
        update();
        return;
    }
    
    // 获取在远程屏幕上的坐标
    QPoint remotePos = mapToRemote(event->pos());
    
    // 只有当位置有真正变化时才发送
    static QPoint lastRemotePos;
    if (remotePos != lastRemotePos) {
        lastRemotePos = remotePos;
        emit mouseMoved(remotePos.x(), remotePos.y());
    }
    
    // 更新视图以显示新的光标位置
    update();
}

void ScreenViewer::keyPressEvent(QKeyEvent *event)
{
    if (!controlEnabled || remoteScreen.isNull()) {
        return;
    }
    
    // 防止重复按键
    if (event->isAutoRepeat()) {
        return;
    }
    
    int key = event->key();
    LOG_INFO(QString("键盘按下: 键值=%1").arg(key));
    
    emit keyPressed(key);
}

void ScreenViewer::keyReleaseEvent(QKeyEvent *event)
{
    if (!controlEnabled || remoteScreen.isNull()) {
        return;
    }
    
    // 防止重复按键
    if (event->isAutoRepeat()) {
        return;
    }
    
    int key = event->key();
    LOG_INFO(QString("键盘释放: 键值=%1").arg(key));
    
    emit keyReleased(key);
}

void ScreenViewer::resizeEvent(QResizeEvent *event)
{
    QWidget::resizeEvent(event);
    
    // 强制重绘
    update();
}

QPoint ScreenViewer::mapToRemote(const QPoint &localPos)
{
    if (remoteScreen.isNull() || remoteScreenSize.isEmpty()) {
        return localPos;
    }
    
    QRect targetRect;
    
    switch (scaleMode) {
    case NoScale:
        // 不缩放，原始大小显示
        targetRect = QRect(0, 0, remoteScreen.width(), remoteScreen.height());
        
        // 如果图像大于窗口，则将其居中
        if (remoteScreen.width() > width() || remoteScreen.height() > height()) {
            targetRect.moveCenter(rect().center());
        }
        break;
        
    case ScaleToFit:
        // 缩放以适应窗口大小
        targetRect = rect();
        break;
        
    case ScaleKeepRatio:
        // 保持宽高比
        targetRect = rect();
        
        qreal scaleX = (qreal)width() / remoteScreen.width();
        qreal scaleY = (qreal)height() / remoteScreen.height();
        qreal scale = qMin(scaleX, scaleY);
        
        int newWidth = remoteScreen.width() * scale;
        int newHeight = remoteScreen.height() * scale;
        
        targetRect.setSize(QSize(newWidth, newHeight));
        targetRect.moveCenter(rect().center());
        break;
    }
    
    // 检查点是否在目标矩形内
    if (!targetRect.contains(localPos)) {
        return QPoint(-1, -1);  // 返回无效坐标
    }
    
    // 将本地坐标映射到远程屏幕坐标
    qreal xRatio = (localPos.x() - targetRect.left()) / (qreal)targetRect.width();
    qreal yRatio = (localPos.y() - targetRect.top()) / (qreal)targetRect.height();
    
    int remoteX = xRatio * remoteScreenSize.width();
    int remoteY = yRatio * remoteScreenSize.height();
    
    return QPoint(remoteX, remoteY);
}

QPoint ScreenViewer::mapToLocal(const QPoint &remotePos)
{
    if (remoteScreen.isNull() || remoteScreenSize.isEmpty()) {
        return remotePos;
    }
    
    QRect targetRect;
    
    switch (scaleMode) {
    case NoScale:
        // 不缩放，原始大小显示
        targetRect = QRect(0, 0, remoteScreen.width(), remoteScreen.height());
        
        // 如果图像大于窗口，则将其居中
        if (remoteScreen.width() > width() || remoteScreen.height() > height()) {
            targetRect.moveCenter(rect().center());
        }
        break;
        
    case ScaleToFit:
        // 缩放以适应窗口大小
        targetRect = rect();
        break;
        
    case ScaleKeepRatio:
        // 保持宽高比
        targetRect = rect();
        
        qreal scaleX = (qreal)width() / remoteScreen.width();
        qreal scaleY = (qreal)height() / remoteScreen.height();
        qreal scale = qMin(scaleX, scaleY);
        
        int newWidth = remoteScreen.width() * scale;
        int newHeight = remoteScreen.height() * scale;
        
        targetRect.setSize(QSize(newWidth, newHeight));
        targetRect.moveCenter(rect().center());
        break;
    }
    
    // 将远程坐标映射到本地坐标
    qreal xRatio = remotePos.x() / (qreal)remoteScreenSize.width();
    qreal yRatio = remotePos.y() / (qreal)remoteScreenSize.height();
    
    int localX = targetRect.left() + xRatio * targetRect.width();
    int localY = targetRect.top() + yRatio * targetRect.height();
    
    return QPoint(localX, localY);
}

qreal ScreenViewer::calculateScale() const
{
    if (remoteScreen.isNull() || remoteScreenSize.isEmpty()) {
        return 1.0;
    }
    
    qreal scaleX = (qreal)width() / remoteScreenSize.width();
    qreal scaleY = (qreal)height() / remoteScreenSize.height();
    
    switch (scaleMode) {
    case NoScale:
        return 1.0;
    case ScaleToFit:
        return qMin(scaleX, scaleY);
    case ScaleKeepRatio:
        return qMin(scaleX, scaleY);
    default:
        return 1.0;
    }
}

bool ScreenViewer::loadImage(const QByteArray &imageData)
{
    if (imageData.isEmpty()) {
        LOG_WARNING("收到空的图像数据");
        return false;
    }
    
    // 从字节数组加载图像
    QImage newImage;
    if (!newImage.loadFromData(imageData)) {
        LOG_ERROR("无法加载图像数据");
        return false;
    }
    
    // 更新远程屏幕图像
    remoteScreen = newImage;
    
    // 如果尚未设置远程屏幕尺寸，则从图像获取
    if (remoteScreenSize.isEmpty()) {
        setRemoteScreenSize(newImage.width(), newImage.height());
    }
    
    return true;
} 